package com.glzn.springboot03.mqtt;

import com.glzn.springboot03.entity.Mqtt;
import com.glzn.springboot03.service.MqttService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @author gongjq
 */
@Component
public class MqttConfig {
	@Autowired
	MqttService mqttService;

	private List<MqttPublishClient> publishClientList = new ArrayList<>();

	@Bean
	public List<MqttPublishClient> getPublishClients() {
		if (publishClientList.size() <= 0) {
			List<Mqtt> mqttList = mqttService.findAll();
			for (Mqtt mqtt : mqttList) {
				MqttPublishClient mqttPublishClient = new MqttPublishClient();
				mqttPublishClient.getInstance(mqtt);

				publishClientList.add(mqttPublishClient);
			}
		}
		return publishClientList;
	}

	public static String sign(Map<String, String> params, String deviceSecret, String signMethod) {
		//将参数Key按字典顺序排序
		String[] sortedKeys = params.keySet().toArray(new String[] {});
		Arrays.sort(sortedKeys);

		//生成规范化请求字符串
		StringBuilder canonicalizedQueryString = new StringBuilder();
		for (String key : sortedKeys) {
			if ("sign".equalsIgnoreCase(key)) {
				continue;
			}
			canonicalizedQueryString.append(key).append(params.get(key));
		}

		try {
			String key = deviceSecret;
			return encryptHMAC(signMethod,canonicalizedQueryString.toString(), key);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public static String encryptHMAC(String signMethod,String content, String key) throws Exception {
		SecretKey secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), signMethod);
		Mac mac = Mac.getInstance(secretKey.getAlgorithm());
		mac.init(secretKey);
		byte[] data = mac.doFinal(content.getBytes(StandardCharsets.UTF_8));
		return bytesToHexString(data);
	}

	public static final String bytesToHexString(byte[] bArray) {

		StringBuffer sb = new StringBuffer(bArray.length);
		String sTemp;
		for (int i = 0; i < bArray.length; i++) {
			sTemp = Integer.toHexString(0xFF & bArray[i]);
			if (sTemp.length() < 2) {
				sb.append(0);
			}
			sb.append(sTemp.toUpperCase());
		}
		return sb.toString();
	}
}
